package model.market;

import java.io.Serializable;
import java.util.List;


public class MarketConfig implements Serializable{
	
	public enum VolatilityAdjustment{
		NO_ADJUSTMENT("Unadjusted"),ADJUSTED("50/50 Adjusted"),FIXED("Fixed");
		
		private VolatilityAdjustment(String title){
			this.title=title;
		}
		private String title;
		public String toString(){
			return title;
		}
	}
	
	private VolatilityAdjustment volatilityAdjustment=VolatilityAdjustment.NO_ADJUSTMENT;
	
	public VolatilityAdjustment getVolatilityAdjustment() {
		return volatilityAdjustment;
	}
	
	public void setVolatilityAdjustment(
			VolatilityAdjustment volatilityAdjustment) {
		this.volatilityAdjustment = volatilityAdjustment;
	}
	
	public enum SharpeMultiplier{
		LOW_LEVERAGE(1,"1"),MEDIUM_LEVERAGE(3,"3"),HIGH_LEVERAGE(7,"7"),VERY_HIGH_LEVERAGE(10,"10"),SUPER_LEVERAGE(15,"15"),SUPER_PLUS_LEVERAGE(30,"30"),SUPER_PLUS_2_LEVERAGE(60,"60"),SUPER_DUPER_LEVERAGE(70,"Super-Duper");
		
		public int multiplier;
		
		public String display;
		
		private SharpeMultiplier(int multiplier,String display){
			this.multiplier=multiplier;
			this.display=display;
		}
		
		public String toString(){
			return display;
		}
	}
	
	private RateProvider rateProvider;
	
	public static final String APPETITE_STD_DEV="Target 10% Annual Std. dev.";
	public static final String APPETITE_SHARPE_RELATED="Proportional to anticipated sharpe";
//AM: not supported at the moment	public static final String APPETITE_MARKET_SHARPE_RELATED="Proportional to market sharpe";
//AM: not suupported at the moment	public static final String APPETITE_FIXED_SHARPE_RELATED="Proportional to sharpe ratio";
	public static final String APPETITE_FIXED="Fixed: 100% Funds Invested";
//AM: not supported at the moment.	public static final String APPETITE_LEVERED="Fixed Lever: 120% Funds Invested";
//AM: not supported at the moment..	public static final String APPETITE_FIXED_SHARPE_BINARY="Binary sharpe of .3";
	
	
	public static final int TRADE_STRAT_EMH = 1;
	public static final int TRADE_STRAT_ADJ = 2;
	
	public static final String BETA_UNADJUSTED="Unadjusted";
	public static final String BETA_BLOOMBERG = "Bloomberg style";
	public static final String BETA_FIXED = "Fixed: 1";
	public static final String BETA_STD_ERR = "Standard error adj.";
	
	public static final String ERP_FIXED = "Fixed (from above)";
	public static final String ERP_OBSERVED = "Observed";
	
	private SharpeMultiplier sharpeMultiplier=SharpeMultiplier.LOW_LEVERAGE;
	/**
	 * The number of periods the market engine will run before traders can trade.
	 */
	private int tradeDelay=40;
	private boolean oscillateRiskFree = true;
	private int numberOfAssets=5;
	
	private double riskFreeRate = .03;//1%
	private  double shareCashflowRate = .05;//1% 
	private double volatility=.3;
	private double volatilityAsset0 = .3;
	private int periodsInYear=10;
	private double asset0Shock = 0;
	private int seedRandom = 1;
	private FinanceCharges financeCharge=FinanceCharges.RF;
	private int tradeStrategy = TRADE_STRAT_EMH;
	private int iterations=100;
	private String betaCalculation=BETA_UNADJUSTED;
	private String erpCalculation = ERP_OBSERVED;
	private String appetite = APPETITE_SHARPE_RELATED;
	
	//AMXX: .bind this in.
	private int tradesPerDay=1;
	
	private int periodsPerSampleForRegression=1;
	

	private boolean allowAllAssetTrades=true;
	
	
	private int liquidity;

	private double subtractFractionShock;
	
	public double getSubtractFractionShock() {
		return subtractFractionShock;
	}

	public void setSubtractFractionShock(double subtractFractionShock) {
		this.subtractFractionShock = subtractFractionShock;
	}

	public void setLiquidity(int liquidity) {
		this.liquidity = liquidity;
	}
	
	public int getLiquidity() {
		return liquidity;
	}
	
	public int getPeriodsPerSampleForRegression() {
		return periodsPerSampleForRegression;
	}
	
	public void setPeriodsPerSampleForRegression(int periodsPerSampleForRegression) {
		this.periodsPerSampleForRegression = periodsPerSampleForRegression;
	}
	
	
	
	public boolean isAllowAllAssetTrades() {
		return allowAllAssetTrades;
	}

	public void setAllowAllAssetTrades(boolean allowAllAssetTrades) {
		this.allowAllAssetTrades = allowAllAssetTrades;
	}

	public int getTradesPerDay() {
		return tradesPerDay;
	}

	public void setTradesPerDay(int tradesPerDay) {
		this.tradesPerDay = tradesPerDay;
	}

	public SharpeMultiplier getSharpeMultiplier() {
		return sharpeMultiplier;
	}
	
	public void setSharpeMultiplier(SharpeMultiplier sharpeMultiplier) {
		this.sharpeMultiplier = sharpeMultiplier;
	}
	
	public String getAppetite() {
		return appetite;
	}
	
	public void setAppetite(String appetite) {
		this.appetite = appetite;
	}
	
	public String getErpCalculation() {
		return erpCalculation;
	}
	
	public void setErpCalculation(String erpCalculation) {
		this.erpCalculation = erpCalculation;
	}
	
	public String getBetaCalculation() {
		return betaCalculation;
	}
	
	public void setBetaCalculation(String betaCalculation) {
		this.betaCalculation = betaCalculation;
	}
	
	public int getIterations() {
		return iterations;
	}
	
	public void setIterations(int iterations) {
		this.iterations = iterations;
	}
	
	public int getTradeStrategy() {
		return tradeStrategy;
	}
	
	public void setTradeStrategy(int tradeStrategy) {
		this.tradeStrategy = tradeStrategy;
	}
	
	public FinanceCharges getFinanceCharge() {
		return financeCharge;
	}
	
	public void setFinanceCharge(FinanceCharges financeCharge) {
		this.financeCharge = financeCharge;
	}
	
	
	
	public void setRateProvider(RateProvider rateProvider) {
		this.rateProvider = rateProvider;
	}
	
	public RateProvider getRiskFreeRateProvider(){
		if(rateProvider!=null){
			return rateProvider;
		}
		
		if(getOscillateRiskFree()){
			return new OscillatingRiskFreeRateProvider();
		}else{
			return null;
		}
		
		
	}
	
	
	
	public boolean getOscillateRiskFree() {
		return oscillateRiskFree;
	}
	
	public void setOscillateRiskFree(boolean oscillateRiskFree) {
		this.oscillateRiskFree = oscillateRiskFree;
	}
	
	public int getSeedRandom() {
		
		return seedRandom;
	}
	
	public void setSeedRandom(int seedRandom) {
		this.seedRandom = seedRandom;
	}
	
	
	public double getAsset0Shock() {
		return asset0Shock;
	}
	
	public void setAsset0Shock(double asset0Shock) {
		this.asset0Shock = asset0Shock;
	}
	
	
	public double getVolatility() {
		return volatility;
	}
	
	public int getPeriodsInYear() {
		return periodsInYear;
	}
	
	public void setPeriodsInYear(int periodsInYear) {
		this.periodsInYear = periodsInYear;
	}
	
	public void setVolatility(double volatility) {
		this.volatility = volatility;
	}
	
	public double getInitialRiskFreeRate() {
		return riskFreeRate;
	}

	public void setRiskFreeRate(double riskFreeRate) {
		this.riskFreeRate = riskFreeRate;
	}


	public double getShareCashflowRate() {
		return shareCashflowRate;
	}


	public void setShareCashflowRate(double shareCashflowRate) {
		this.shareCashflowRate = shareCashflowRate;
	}

	
	public void setTradeDelay(int tradeDelayParam){
		tradeDelay=tradeDelayParam;
	}
	
	public int getTradeDelay(){
		return tradeDelay;
	}

	public int getNumberOfAssets() {
		return numberOfAssets;
	}


	public void setNumberOfAssets(int numberOfAssets) {
		this.numberOfAssets = numberOfAssets;
	}

	public double getVolatilityAsset0() {
		return volatilityAsset0;
	}
	
	
	public void setVolatilityAsset0(double volatilityAsset0) {
		this.volatilityAsset0 = volatilityAsset0;
	}
	
	public boolean newDawn(int period) {
		return period % getTradesPerDay() == 0;
	}
	
}
